home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows 95 API Bible
/
Windows 95 API Bible 3 Disc Set.iso
/
Win32 API Bible Book 1 of 3
/
CHAPTE18
/
EX6.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-26
|
11KB
|
317 lines
/* snapw32.c - program to capture screen display to clipboard */
#include <windows.h>
#include <snapw32.h>
// prototype for main entry point.
int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow );
// prototype for windows message handler for class "ATOM"
LRESULT CALLBACK WndProc( HANDLE, UINT, WPARAM, LPARAM );
LRESULT CALLBACK GrabProc( HANDLE, UINT, WPARAM, LPARAM );
// outline block subroutine
void OutlineBlock (HWND hWnd, POINTS beg, POINTS end);
// instance data
HWND hMainWnd = 0; // handle of main window
HWND hGrabWnd = 0; // window used to grab screen
HANDLE hInst = 0; // handle of program instance
char szBuffer[256]; // work area for print formatting
int PASCAL WinMain( HANDLE hInstance, // this instance
HANDLE hPrevInstance, // always 0 in win32
LPSTR lpCmdLine, // command line arguments
int nCmdShow ) // always SW_SHOWDEFAULT in win32
{
WNDCLASS wc; // buffer to pass when registering class
MSG msg; // buffer to store windows messages
hInst = hInstance; // store instance in instance data.
// Fill out Class Data for User-Interface Window.
wc.style =(WORD)NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hCursor = (HCURSOR) LoadCursor( (HANDLE)NULL, IDC_ARROW );
wc.hbrBackground = GetStockObject( WHITE_BRUSH );
wc.lpszMenuName = "SNAPW32";
wc.lpfnWndProc = WndProc;
wc.lpszClassName = "SNAPW32";
if (RegisterClass( &wc ) == 0)
return FALSE;
// Fill out Class Data for invisible window that is used to capture image.
wc.style =(WORD)NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hCursor = NULL;
wc.hbrBackground = GetStockObject( NULL_BRUSH );
wc.lpszMenuName = NULL;
wc.lpfnWndProc = GrabProc;
wc.lpszClassName = "GRAB";
if (RegisterClass( &wc ) == 0)
return FALSE;
hMainWnd = CreateWindow( "SNAPW32",
"SNAP!",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // no parent
NULL, // use class menu
hInstance,
NULL );
if(!hMainWnd)
return( FALSE );
ShowWindow( hMainWnd, nCmdShow );
UpdateWindow( hMainWnd );
hGrabWnd = CreateWindow( "GRAB",
"",
WS_POPUP,
0,
- GetSystemMetrics(SM_CYCAPTION), // above screen.
GetSystemMetrics(SM_CXSCREEN), // size of screen
GetSystemMetrics(SM_CYSCREEN),
NULL, // no parent
NULL, // no menu
hInstance,
NULL );
if(!hGrabWnd)
return(FALSE);
// don't show grab window yet.
while( GetMessage( &msg, NULL, 0, 0 ) ) {
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
// grabbing global data shared between grab window and snapw32.
static BOOL bCapturing = FALSE;
static BOOL bBlocking = FALSE;
static POINTS beg, end, oldend;
static short xSize, ySize;
//
// This is the window message procedure for the user-interface window.
// This is the window that responds to menu requests and invokes the
// screen capture window, "GRAB".
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) /* process Windows messages */
{
case WM_COMMAND: /* one of the menu items */
switch (wParam)
{
case IDM_START: /* the start capture item */
bCapturing = TRUE;
bBlocking = FALSE;
ShowWindow( hWnd, SW_HIDE );
// need to let screen recover here
Sleep( 0 );
ShowWindow( hGrabWnd, SW_SHOWNORMAL );
SetCapture( hGrabWnd ); /* grab mouse */
break;
case IDM_CLEAR: /* clears screen and clipboard */
OpenClipboard( hWnd );
EmptyClipboard( );
CloseClipboard( );
InvalidateRect( hWnd, NULL, TRUE );
break ;
case IDM_EXIT:
DestroyWindow( hGrabWnd );
DestroyWindow( hWnd );
break ;
case IDM_ABOUT: /* show about box */
MessageBox( hWnd,
"SnapW32 - Windows 95 screen capture to clipboard.\nThe Waite Group 1994.",
"SnapW32 About", MB_OK );
break ;
case IDM_HELP:
MessageBox ( hWnd, "After clicking the Start Capture\
menu item, move the mouse to the upper left of\
the area you want to copy to the clipboard.\
Hold down the left mouse button while you drag the\
mouse to the lower right of the area. Once you\
release the mouse button, the area is sent to the\
clipboard and shown in SnapW32's window.",
"SnapW32 Help", MB_OK );
break;
}
break;
case WM_PAINT:
{
/* display contents of clipboard if bitmap */
HDC hDC, hMemDC;
BITMAP bm;
HBITMAP hBitmap;
PAINTSTRUCT ps;
hDC = BeginPaint( hWnd, &ps );
OpenClipboard( hWnd );
if ((hBitmap = GetClipboardData( CF_BITMAP ))!=0)
{
// Display CF_BITMAP contents of clipboard in client area.
HBITMAP hOldBitmap;
hMemDC = CreateCompatibleDC( hDC );
hOldBitmap = SelectObject( hMemDC, hBitmap );
GetObject( hBitmap, sizeof (BITMAP), (LPSTR) &bm );
SetStretchBltMode( hDC, COLORONCOLOR );
StretchBlt( hDC, 0, 0, xSize, ySize, hMemDC, 0, 0,
bm.bmWidth, bm.bmHeight, SRCCOPY );
SelectObject( hDC, hOldBitmap );
DeleteDC( hMemDC );
}
CloseClipboard( );
EndPaint( hWnd, &ps );
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc (hWnd, uMsg, wParam, lParam) ;
}
return( 0L );
}
//
// This is the window that is displayed while the user captures the screen
// image. It is a transparent window so that the data beneath can be seen.
//
//
LRESULT CALLBACK GrabProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC, hMemDC ;
BITMAP bm ;
HBITMAP hBitmap ;
PAINTSTRUCT ps ;
switch (uMsg) /* process Windows messages */
{
case WM_LBUTTONDOWN: /* starting capturing screen */
if (bCapturing)
{
bBlocking = TRUE;
oldend = beg = MAKEPOINTS( lParam );
OutlineBlock( hWnd, beg, oldend );
SetCursor( LoadCursor( NULL, IDC_CROSS ) );
}
break;
case WM_MOUSEMOVE: /* show area as rectangle on screen */
if (bBlocking)
{
end = MAKEPOINTS( lParam );
OutlineBlock( hWnd, beg, oldend ); /* erase outline */
OutlineBlock( hWnd, beg, end ); /* draw new one */
oldend = end;
}
break;
case WM_LBUTTONUP: /* capture and send to clipboard */
if (bBlocking)
{
bBlocking = bCapturing = FALSE ;
SetCursor( LoadCursor( NULL, IDC_ARROW ) );
ReleaseCapture( ); /* free mouse */
end = MAKEPOINTS( lParam );
OutlineBlock( hWnd, beg, oldend );
xSize = abs( beg.x - end.x );
ySize = abs( beg.y - end.y );
hDC = GetDC( hWnd );
hMemDC = CreateCompatibleDC( hDC );
hBitmap = CreateCompatibleBitmap( hDC, xSize, ySize );
if (hBitmap)
{
SelectObject( hMemDC, hBitmap );
StretchBlt( hMemDC, 0, 0, xSize, ySize,
hDC, beg.x, beg.y, end.x - beg.x,
end.y - beg.y, SRCCOPY );
OpenClipboard( hWnd );
EmptyClipboard( ) ;
SetClipboardData( CF_BITMAP, hBitmap );
CloseClipboard( );
InvalidateRect( hWnd, NULL, TRUE );
}
else
MessageBeep( 0 );
DeleteDC( hMemDC );
ReleaseDC( hWnd, hDC );
}
ShowWindow( hGrabWnd, SW_HIDE );
ShowWindow( hMainWnd, SW_RESTORE ); /* un-minimize window */
break;
case WM_PAINT:
ValidateRect( hWnd, NULL );
break;
default:
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
return (0L) ;
}
/* OutlineBlock() writes a rectangle on the screen given the two corner */
/* points. The R2_NOT style is used, so drawing twice on the same location */
/* erases the outline. */
void OutlineBlock( HWND hWnd, POINTS beg, POINTS end )
{
HDC hDC ;
POINT ptBeg;
POINT ptEnd;
/* convert mouse 16 bit POINTS to WIN32 POINT Structure that GDI likes */
ptBeg.x = beg.x;
ptEnd.x = end.x;
ptBeg.y = beg.y;
ptEnd.y = end.y;
hDC = CreateDC( "DISPLAY", NULL, NULL, NULL );
ClientToScreen( hWnd, &ptBeg ); /* convert to screen units */
ClientToScreen( hWnd, &ptEnd );
SetROP2( hDC, R2_NOT ); /* use logical NOT pen */
MoveToEx( hDC, ptBeg.x, ptBeg.y, NULL ); /* draw rectangle */
LineTo( hDC, ptEnd.x, ptBeg.y );
LineTo( hDC, ptEnd.x, ptEnd.y );
LineTo( hDC, ptBeg.x, ptEnd.y );
LineTo( hDC, ptBeg.x, ptBeg.y );
DeleteDC( hDC );
}